#include "main.h"
#include "pca.h"

sbit LED = P3^6;
sbit KEY = P1^2;

volatile uint16_t xdata task1;
volatile uint16_t xdata task2;
volatile uint8_t OutPwmduty;

uint16_t Run_time;

#define DEF_FAN_SPEED (450)
#define ARG_CAL_NUM 10
uint16_t xdata ICfreq[ARG_CAL_NUM] = {0};
uint8_t xdata ICfreq_index;

uint16_t xdata ICpwmDuty_arr[ARG_CAL_NUM] = {0};
uint8_t xdata ICpwmDuty_index;

uint16_t xdata IC_Pwm_Duty_Avg;
uint16_t xdata IC_Freq_Avg;
uint16_t xdata OUT_Pwm_Duty;
uint16_t xdata OUT_Freq;

work_mode_e xdata mode; 

uint16_t xdata freq_threshold_value;
uint16_t xdata pwm_threshold_value;

void Delay1ms()		//@22.1184MHz
{
	unsigned char i, j;

	i = 29;
	j = 183;
	do
	{
		while (--j);
	} while (--i);
}


uint16_t get_avg(uint16_t *arr,uint8_t len)
{
	uint16_t max;
	uint16_t min;
	uint32_t sum;
	uint8_t i;
	
	min = 0xffff;
	max = 0;
	sum = 0;
	
	for(i = 0; i < len; i++)
	{
			if(arr[i] > max)
			{
					max = arr[i];
			}
			if(arr[i] < min)
			{
				  min = arr[i];
			}
			sum += arr[i];
	}
	
	sum -= (max + min);
	
	return sum/(len - 2);	
}

uint16_t get_ICfreq(void)
{
	
	ICfreq[ICfreq_index] = SYSCLK_12/InputCapture;
	if(InputCapture == 0)
	{
		ICfreq[ICfreq_index] = 0;
	}

	if(++ICfreq_index >= ARG_CAL_NUM)
	{
			ICfreq_index = 0;
	}
	
	return get_avg(ICfreq,ARG_CAL_NUM);
}

uint16_t get_ICpwmDuty(void)
{
		uint32_t ICpwmPeriod;
		uint16_t ICpwmDuty;
	
		ICpwmPeriod = lowLevelTime + highLevelTime;
		ICpwmDuty = (highLevelTime*100)/ICpwmPeriod;
		if (ICpwmDuty > 100) ICpwmDuty = 0;
	
		ICpwmDuty_arr[ICpwmDuty_index] = ICpwmDuty;
		if (++ICpwmDuty_index >= ARG_CAL_NUM)
		{
				ICpwmDuty_index = 0;
		}
	
		return get_avg(ICpwmDuty_arr,ARG_CAL_NUM);
}

uint16_t CalculateFanDuty(void)
{
	uint16_t speed;
	speed = IC_Freq_Avg*30;
	if (speed > (DEF_FAN_SPEED+20))
	{
		if (--OUT_Pwm_Duty <= 3)
		{
			OUT_Pwm_Duty = 3;
		}
	}
	else if (speed < (DEF_FAN_SPEED-20))
	{
		if (++OUT_Pwm_Duty >= 99)
		{
			OUT_Pwm_Duty = 99;
		}
	}
	return OUT_Pwm_Duty;
}

void main()
{
	uint16_t count,count2;
	uint8_t data1,data2;
	
	P0M0 = 0x00;
	P0M1 = 0x00;
	P1M0 = 0x00;
	P1M1 = 0x00;
	P2M0 = 0x00;
	P2M1 = 0x00;
	P3M0 = 0x00;
	P3M1 = 0x00;
	P4M0 = 0x00;
	P4M1 = 0x00;
	P5M0 = 0x00;
	P5M1 = 0x00;

	Uart_init();
	Timer_Init();
	pca_init();
	EA = 1;

	printf("UartSendStrTest\r\n");
	printf("time:%s\r\n",__TIME__);
	
	ICfreq_index = 0;
	ICpwmDuty_index = 0;

	data1 = IapRead(0x0100);
	data2 = IapRead(0x0101);
	freq_threshold_value = (data1 << 8) | data2;
	
	if(freq_threshold_value == 0xffff) freq_threshold_value = 20;
	
	data1 = IapRead(0x0102);
	data2 = IapRead(0x0103);
	pwm_threshold_value = (data1 << 8) | data2;
	if(pwm_threshold_value == 0xffff) pwm_threshold_value = 20;
	
	count = 0;
	count2 = 1;
	
	task1 = 200;
	task2 = 200;
	Run_time = 0;
	mode = TRANS_MODE;
	
	while (1)
	{
		if ((KEY == 0))
		{
			if(count2 >= 1)
			{
					if (++count2 >= 10)
					{
						count2 = 0;
						if (mode != SET_MODE)
						{
							mode = SET_MODE;
						}
						else if (mode == SET_MODE)
						{
							freq_threshold_value = IC_Freq_Avg + 2;
							IapErase(0x0100);
							data1 = freq_threshold_value >> 8;
							data2 = freq_threshold_value;
							IapProgram(0x0100,data1);
							IapProgram(0x0101,data2);
							
							pwm_threshold_value = IC_Pwm_Duty_Avg + 2;
							data1 = pwm_threshold_value >> 8;
							data2 = pwm_threshold_value;
							IapProgram(0x0102,data1);
							IapProgram(0x0103,data2);
							mode = TRANS_MODE;
						}
					}
			}
		}
		else
		{
			count2 = 1;
		}

		if (task1 >= 50)
		{
			task1 = 0;
			IC_Pwm_Duty_Avg = get_ICpwmDuty();
			IC_Freq_Avg = get_ICfreq();
		}
		if (task2 >= 50){
			task2 = 0;
			if (Run_time >= 2400)
			{
				Run_time = 2400;
				if ((IC_Pwm_Duty_Avg >= pwm_threshold_value) && (mode != SET_MODE))
				{
					mode = TRANS_MODE;
				}
				else if((IC_Pwm_Duty_Avg < (pwm_threshold_value - 1)) && (mode != SET_MODE))
				{
					mode = SILENCE_MODE;
				}
			}
			else
			{
				Run_time++;
				mode = TRANS_MODE;
			}

			if (mode == TRANS_MODE)
			{
				OUT_Pwm_Duty = IC_Pwm_Duty_Avg;
				OUT_Freq = IC_Freq_Avg;
				LED = 0;
			}
			else if (mode == SILENCE_MODE)
			{
				OUT_Pwm_Duty = CalculateFanDuty();
				OUT_Freq = freq_threshold_value;
				if (++count >= 10)
				{
					count = 0;
					LED = !LED;
				}
			}
			else if (mode == SET_MODE)
			{				
				OUT_Pwm_Duty = IC_Pwm_Duty_Avg;
				OUT_Freq = IC_Freq_Avg;
				if (++count >= 2)
				{
					count = 0;
					LED = !LED;
				}
			}
			
			SetPwmDuty(100 - OUT_Pwm_Duty);
			SetPulseFreq(OUT_Freq);
			
			printf("OUT_Pwm_Duty:%u \t",(uint16_t)OUT_Pwm_Duty);
			
			printf("freq_threshold_value:%u \t",freq_threshold_value);
			printf("pwm_threshold_value:%u \t",pwm_threshold_value);
			printf("IC_Freq_Avg:%u \t",IC_Freq_Avg);
			printf("IC_Pwm_Duty_Avg:%u\t",IC_Pwm_Duty_Avg);
			printf("\r\n");
			
		}
		Delay1ms();
//		if(rx1_sta & 0x80)Uart1_handle();
	}
}
